package neo.tetris.bean.model.tetris;

import neo.tetris.bean.model.tetris.Shape.Tetrominoes;

public class Tetris {
	final public int boardWidth;
	final public int boardHeight;
	final public Tetrominoes[] board;
	public Shape curPiece;
	public int numLinesRemoved = 0;
	
	public Tetris() {
		this(10, 22);
	}

	public Tetris(int width, int height) {
		super();

		this.boardWidth = width;
		this.boardHeight = height;
		this.curPiece = new Shape();
		this.board = new Tetrominoes[boardWidth * boardHeight];
		clearBoard();
	}

	public Tetrominoes shapeAt(int x, int y) {
		return board[(y * boardWidth) + x];
	}

	public void dropDown(int curX, int curY) {
		int newY = curY;
		while (newY > 0) {
			if (!tryMove(curPiece, curX, newY - 1))
				break;
			--newY;
		}
		pieceDropped(curX, curY);
	}

	public void clearBoard() {
		for (int i = 0; i < boardHeight * boardWidth; ++i)
			board[i] = Tetrominoes.NoShape;
	}

	public void pieceDropped(int curX, int curY) {
		for (int i = 0; i < 4; ++i) {
			int x = curX + curPiece.x(i);
			int y = curY - curPiece.y(i);
			board[(y * boardWidth) + x] = curPiece.getShape();
		}

		removeFullLines();

		newPiece();
	}

	public void newPiece() {
		curPiece.setRandomShape();
	}

	public boolean tryMove(Shape newPiece, int newX, int newY) {
		for (int i = 0; i < 4; ++i) {
			int x = newX + newPiece.x(i);
			int y = newY - newPiece.y(i);
			if (x < 0 || x >= boardWidth || y < 0 || y >= boardHeight)
				return false;
			if (shapeAt(x, y) != Tetrominoes.NoShape)
				return false;
		}
		return true;
	}

	private void removeFullLines() {
		int numFullLines = 0;

		for (int i = boardHeight - 1; i >= 0; --i) {
			boolean lineIsFull = true;

			for (int j = 0; j < boardWidth; ++j) {
				if (shapeAt(j, i) == Tetrominoes.NoShape) {
					lineIsFull = false;
					break;
				}
			}

			if (lineIsFull) {
				++numFullLines;
				for (int k = i; k < boardHeight - 1; ++k) {
					for (int j = 0; j < boardWidth; ++j)
						board[(k * boardWidth) + j] = shapeAt(j, k + 1);
				}
			}
		}

		if (numFullLines > 0) {
			numLinesRemoved += numFullLines;
//			statusbar.setText(String.valueOf(numLinesRemoved));
			curPiece.setShape(Tetrominoes.NoShape);
		}
	}
	
	public void addLine(int num) {
		for (int i = 0; i < num; i++) {
			for (int c = 0; c < boardWidth; c++) {
			}
		}
	}
}
